package functions;

import java.awt.Graphics;
import java.awt.Polygon;
import javax.swing.JPanel;
import main.ColorScheme;

/**
 * Abstract class for function panels.
 * @author Patrick
 */
public abstract class AbstractPanel extends JPanel {

    /**
    * Local colorscheme variable
    */
    int colorScheme;

    /**
     * Polygon variable for storing function values
     */
    Polygon function = null;

    /**
     * Abstract constructor for functionpanels
     * @param colorScheme given colorScheme index for this panel
     */
    AbstractPanel(int colorScheme) {
        this.colorScheme = colorScheme;
    }


    /**
     * Generic paint function for further paint calls
     * @param g GraphicsObject
     */
    public void paint(Graphics g) {
        super.paint(g);
        
        this.paintBackground(g);
        this.paintCoordinateSystem(g);
        this.paintFunction(g);
    }

    /**
     * Fills the panel background
     * @param g GraphicsObject
     */
    private void paintBackground(Graphics g) {
        g.setColor(ColorScheme.colorSchemes[this.colorScheme][0]);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());
    }

    /**
     * Paints a coordinate system on the panel
     * @param g GraphicsObject
     */
    private void paintCoordinateSystem(Graphics g) {
        //helping variables for positioning
        int steps = 30;
        int startX = -((this.getWidth() / 2 + steps) / steps);
        int stopX = (this.getWidth()/2 + steps) / steps;
        int startY = -((this.getHeight() / 2 + steps) / steps);
        int stopY = (this.getHeight()/2 + steps) / steps;
       
        //color
        g.setColor(ColorScheme.colorSchemes[this.colorScheme][1]);
        
        //big lines
        g.drawLine(this.getWidth()/2, 0, this.getWidth()/2, this.getHeight());
        g.drawLine(0, this.getHeight()/2, this.getWidth(), this.getHeight()/2);
        
        //x lines
        for(int i = startX ; i <= stopX; i+=1) {
            int x = this.getWidth() / 2 + (i*steps);
            int y = this.getHeight() / 2;
            g.drawLine(x, y-5, x, y+5);
        }
        
        //y lines
        for(int i = startY; i <= stopY; i+=1) {
            int x = this.getWidth() / 2;
            int y = this.getHeight() / 2 + (i*steps);
            g.drawLine(x-5, y, x+5, y);
        }

    }

    /**
     * Paints the function on the panel
     * @param g GraphicsObject
     */
    private void paintFunction(Graphics g) {
        g.setColor(ColorScheme.colorSchemes[this.colorScheme][2]);
        
        if(this.function == null)
            this.fillPolygon();
        
        g.drawPolyline(this.function.xpoints, this.function.ypoints, this.function.npoints);
    }

    /**
     * Fills the Polygon with points from the function
     */
    private void fillPolygon() {
        this.function = new Polygon();
        int steps = 30;
        
        int startX = -((this.getWidth() / 2 + steps) / steps);
        int stopX = (this.getWidth()/2 + steps) / steps;
        
        for(double i = startX ; i <= stopX; i+=0.1) {
            double x = this.getWidth() / 2 + (i*steps);
            double y = this.getHeight() / 2 - (this.getY(i)*steps);
            
            this.function.addPoint((int)x, (int)y);
        }
          
    }

    /**
     * Calculates the y-value to a given x-value
     * @param x x-value of the function
     * @return y-value of the function
     */
    protected double getY(double x) {
        return 0;
    };

        
}
